﻿/****************************** Module Header ******************************\
 * Module Name:  FormSearchBar.cs
 * Module Version:  1.0.0 (2012-10-18)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to process the FormSearchBar.
 * # 1.1.0 (2013-1-24) 新增字段的ID | Name | Type | Default | DataSource功能
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace UCF.Core.Forms.CustomControls.Search
{
    /// <summary>
    /// 高级搜索
    /// </summary>
    public partial class SoSearchAdvanced : Form
    {
        /// <summary>
        /// 获取或设置搜索方法
        /// </summary>
        public Action<string> SearchHandler { get; set; }

        public Action<string> PreviewHandler { get; set; }
        public string SummaryText { get { return lblSummary.Text; } set { lblSummary.Text = value; } }

        /// <summary>
        /// 是否启用调试模式
        /// </summary>
        public bool IsDebug { get; set; }

        /// <summary>
        /// 获取或设置搜索字段
        /// <para>ID | Name | Type | Default | DataSource</para>
        /// </summary>
        public DataTable Fields { get; set; }

        /// <summary>
        /// 是否复合组合查询模式
        /// </summary>
        public bool IsCompositeGroup
        {
            get
            {
                return colLeft.Visible;
            }
            set
            {
                colLeft.Visible = value;
                colRight.Visible = value;
            }
        }

        DateTimePicker dtp = new DateTimePicker() { Visible = false };
        ComboBox cbb = new ComboBox() { Visible = false };
        CheckBox chk = new CheckBox() { Visible = false };

        public SoSearchAdvanced()
        {
            InitializeComponent();

            dtp.Format = DateTimePickerFormat.Custom;
            dtp.CustomFormat = "yyyy-MM-dd";
            dtp.CloseUp += new EventHandler(dtp_CloseUp);
            cbb.SelectedIndexChanged += new EventHandler(cbb_SelectedIndexChanged);
            chk.Click += new EventHandler(chk_Click);
            dgvGroup.Controls.Add(dtp);
            dgvGroup.Controls.Add(cbb);
            dgvGroup.Controls.Add(chk);

            FormsSkinHelper fsh = new FormsSkinHelper(new FormsSkinOfBlue());
            fsh.SetSkin(this.Controls);

        }
        #region 自定义数据控件事件

        private void dtp_CloseUp(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = dtp.Text;
            HideAllControls();
        }
        private void cbb_SelectedIndexChanged(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = cbb.GetSelectedValue();
            HideAllControls();
        }
        private void chk_Click(object s, EventArgs e)
        {
            dgvGroup.CurrentCell.Value = chk.Checked;
            HideAllControls();
        }
        #endregion

        private void FormSearchAdvanced_Load(object sender, EventArgs e)
        {
            colField.SetDataSource(Fields);
            colOperate.SetDataSource(ListItemTable.New<string, string>().Add("=", "等于").Add("<", "小于").Add(">", "大于").Add("<=", "小于等于").Add(">=", "大于等于").Add("<>", "不等于").Add("like", "包含").Add("in", "并值").ToTable());
            colContactor.SetDataSource(ListItemTable.New<string, string>().Add("and", "并且").Add("or", "或者").ToTable());

            lblSummary.Visible = PreviewHandler != null;
            btnPreview.Visible = PreviewHandler != null;
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            SearchHandler(getSearchSql());
        }
        private string getSearchSql()
        {
            int pairCount = 0;
            StringBuilder sb = new StringBuilder(), sbErr = new StringBuilder();
            object v; string voperator, strv;
            int rowCount = dgvGroup.Rows.Count;
            DataRow rSchema;
            foreach (DataGridViewRow r in dgvGroup.Rows)
            {
                if (r.IsNewRow) break;
                // (
                if (colLeft.Visible)
                {
                    v = r.Cells["colLeft"].Value;
                    if (v != null && (bool)v)
                    {
                        pairCount -= 1;
                        sb.Append("(");
                    }
                }
                // field
                v = r.Cells["colField"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("搜索字段不能为空!");
                    break;
                }
                sb.AppendFormat(" {0} ", v);
                rSchema = Fields.Select("ID='{0}'".Fmt(v.ToString())).FirstOrDefault();
                // operate
                v = r.Cells["colOperate"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("操作符不能为空!");
                    break;
                }
                // value
                v = r.Cells["colValue"].Value;
                if (v == null)
                {
                    sbErr.AppendLine("搜索的值不能为空!");
                    break;
                }
                strv = v.ToString().Trim();
                voperator = r.Cells["colOperate"].Value.ToString();
                if (rSchema["Type"].ToString() == "group" && strv.StartsWith("("))
                {
                    sb.Append(" in ");
                }
                else
                {
                    sb.AppendFormat(" {0} ", voperator);
                }
                switch (voperator)
                {
                    case "like":
                        // customize 自定义模糊搜索：^{word}如：^prefix%
                        if (strv.Length > 0 && strv[0] == '^')
                        {
                            sb.AppendFormat(" '{0}' ", strv.Substring(1).Replace("'", ""));
                        }
                        else
                        {
                            sb.AppendFormat(" '%{0}%' ", strv.Replace("'", ""));
                        }
                        break;
                    case "in":
                        sb.AppendFormat(" ({0}) ", strv);
                        break;
                    default:
                        if (rSchema["Type"].ToString() == "group" && strv.StartsWith("("))
                        {
                            sb.AppendFormat(" {0} ", strv);
                        }
                        else
                        {
                            sb.AppendFormat(" '{0}' ", strv.Replace("'", ""));
                        }
                        break;
                }
                // )
                if (colRight.Visible)
                {
                    v = r.Cells["colRight"].Value;
                    if (v != null && (bool)v)
                    {
                        pairCount += 1;
                        sb.Append(")");
                    }
                }
                // contactor
                v = r.Cells["colContactor"].Value;
                if (v == null && r.Index < rowCount - 2)
                {
                    sbErr.AppendLine("条件连接方式不能为空!");
                    break;
                }
                if (r.Index == rowCount - 2) break;
                sb.AppendFormat(" {0} ", v);
            }
            if (IsDebug) MessageBox.Show(sb.ToString());
            if (sbErr.Length > 0)
            {
                MessageBox.Show(sbErr.ToString());
                return string.Empty;
            }
            if (pairCount != 0)
            {
                MessageBox.Show("括号没闭合,请检查!");
                return string.Empty;
            }
            return sb.ToString();
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            HideAllControls();
            this.dgvGroup.Rows.Clear();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void dgvGroup_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == dgvGroup.NewRowIndex) return;
            if (e.ColumnIndex == colRemove.Index)
            {
                if (dgvGroup.Rows.Count == 1) return;
                dgvGroup.Rows.RemoveAt(e.RowIndex);
            }
            if (Fields.Columns.Count < 3) return;
            if (e.ColumnIndex == colValue.Index)
            {
                HideAllControls();
                object ofield = dgvGroup.GetCurrentValue("colField");
                if (ofield == null) return;
                DataRow r = Fields.AsEnumerable().Where(a => a.Field<string>("ID") == ofield.ToString()).FirstOrDefault();
                Rectangle _Rectangle = dgvGroup.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); //得到所在单元格位置和大小
                Size size = new Size(_Rectangle.Width, _Rectangle.Height); //把单元格大小赋给控件
                Point location = new Point(_Rectangle.X, _Rectangle.Y); //把单元格位置赋给控件
                if (r["Type"] == null) return;
                switch (r["Type"].ToString())
                {
                    case "date":
                        dtp.Size = size;
                        dtp.Location = location;
                        dtp.Visible = true;
                        return;
                    case "group":
                        cbb.DataSource = r["DataSource"].ToString().ToDataTable();
                        cbb.DisplayMember = "col1";
                        cbb.ValueMember = "col0";
                        cbb.Size = size;
                        cbb.Location = location;
                        cbb.Visible = true;
                        return;
                    case "bool":
                        cbb.DataSource = "1=是&0=否".ToDataTable();
                        cbb.DisplayMember = "col1";
                        cbb.ValueMember = "col0";
                        cbb.Size = size;
                        cbb.Location = location;
                        cbb.Visible = true;
                        /*
                        chk.Size = size;
                        chk.Location = location;
                        chk.Visible = true;*/
                        return;
                }
                return;
            }
            HideAllControls();
        }
        private void HideAllControls()
        {
            dtp.Visible = false;
            cbb.Visible = false;
            chk.Visible = false;
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            if (PreviewHandler == null) return;
            PreviewHandler(getSearchSql());
        }
    }
}
